[Previous] [Next] [Index] [Thread]

Re: CGI security: Escape newlines.



-- [ From: Zev Davidovics * EMC.Ver #2.5.02 ] --

subject: simple solution...

The easiest way to avoid any problems is to set up a little filter on all of
the cgi's.

What I have on my system is a little c program that checks the parsed query
string, and only admits certain letters that I chose.

This appears to work well for me.
If you can think of any reason why this is not a good solution, I would like
to hear from you.

Zev Davidovics
-------- REPLY, Original message follows --------

Date: Tuesday, 06-Feb-96 04:02 PM

From: Lincoln Stein            \ Internet:    (lstein@kaa.crbm.cnrs-mop.fr)
To:   Jennifer Myers           \ Internet:    (jmyers@marigold.eecs.nwu.edu)
cc:   bugtraq@crimelab.com     \ Internet:    (bugtraq@crimelab.com)
cc:   www-security@ns2.rutgers.edu \ Internet:    (www-security@ns2.rutgers.
edu)

Subject: CGI security: Escape newlines.

In general I think that it's much better to search for and accept only the
good patterns rather than trusting things to work when you exclude the bad
characters.  People forget that the shell isn't the only vulnerable program,
and other programs may be subvertible by input quite distinct from the set
of shell metacharacters.

Lincoln

Jennifer Myers writes:
 > When sending user-supplied data to a shell in a CGI program, it has
 > become common practice among security-conscious CGI authors to remove
 > or escape certain shell metacharacters to avoid them being interpreted
 > by the shell and possibly allowing the user to execute arbritrary
 > commands at his or her will.
 > 
 > There are a good set of security guidelines at:
 > http://www.cerf.net/~paulp/cgi-security/safe-cgi.txt:
 > 
 > That document recommends removing or escaping the following characters
 > in user-supplied data before passing it to a shell:
 > 
 > 	;<>*|`&$!#()[]{}:'"/
 > 
 > There is (at least) one character missing from this list: the new line
 > character.  I have never seen the new line character included in a list
 > of metacharaters to filter.  
 > 
 > A sampling of widely-available CGI programs turned up many that are
 > vulnerable.  Just about any CGI program which "un-hexifies" (converts
 > characters represented by their hex values in a URL by to their actual
 > character) its input and passes that input to a shell is likely to be
 > vulnerable.
 > 
 > Here's a toy example:
 > 
 >   #!/usr/local/bin/perl
 >   # usage: http://your.host/cgi-bin/echo?<string>
 >   # Echos back the QUERY_STRING to the user.
 > 
 >   $| = 1;
 >   $in = $ENV{'QUERY_STRING'};
 >   $in =~ s/%(..)/pack("c",hex($1))/ge;
 > 
 >   # Escape the nasty metacharacters
 >   # (List courtesy of http://www.cerf.net/~paulp/cgi-security/safe-cgi.
txt)
 >   $in =~ s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"])/\\$1/g;
 > 
 >   print "Content-type: text/html\n\n";
 >   system("/bin/echo $in"); 
 > 
 > Install this program in cgi-bin/echo and
 > <http://your.host/cgi-bin/echo?hello%20there>, will return a page
 > containing the text "hello there".
 > 
 > Insert %0A, the newline character, and you can exploit the shell
 > to run any command you wish.
 > 
 > For example, the URL <http://your.host/cgi-bin/echo?%0Acat%20/etc/passwd>
 > will get you the password file.
 > 
 > (In Perl, the call to system() should have broken up the arguments:
 > 	system("/bin/echo", $in);
 > and the problem would disappear.)
 > 
 > While this example uses system() in Perl, the general program will
 > show up whenever a shell is invoked.
 > 
 > THE FIX:
 > 
 > Very simple.  Add the character \n (the new line character) to the
 > list of characters to REMOVE from user-supplied data before
 > suppling it to a shell in a CGI program.
 > 
 >   #!/usr/local/bin/perl 
 >   # usage: http://your.host/cgi-bin/safe-echo?<string>
 >   # Echos back the QUERY_STRING to the user.
 > 
 >   $| = 1;
 >   $in = $ENV{'QUERY_STRING'};
 >   $in =~ s/%(..)/pack("c",hex($1))/ge;
 > 
 >   # Escape the nasty metacharacters
 >   # (List courtesy of http://www.cerf.net/~paulp/cgi-security/safe-cgi.
txt)
 >   $in =~ s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"\n])/\\$1/g;
 > 
 >   # SECURITY FIX: REMOVE NEWLINES
 >   $in =~ tr/\n//d;
 > 
 >   print "Content-type: text/html\n\n";
 >   system("/bin/echo $in"); 
 > 
 > Again, this bug exists in MANY CGI programs.  If you maintain CGI
 > programs on your server, I suggest you check through each of them.
 > I've only looked through several CGI programs, and found the bug on
 > some of them (the authors have been contacted). If I have more time in
 > the near future, I'll post a list of vulnerable programs as well as
 > alerting he authors.  In the meantime, you should check through the
 > source of all of your CGI programs for this bug.
 > 
 > --
 > Jennifer Myers                          http://www.eecs.nwu.edu/~jmyers/
 > 
 > 
 > 


-------- REPLY, End of original message --------